<script setup lang="ts">
import { getConsentParameters, submitApproveScope } from '@/api/login'
import { ElMessage } from 'element-plus'
import { type Ref, ref } from 'vue'

// 获取授权确认信息响应
const consentResult: Ref<any> = ref()
// 所有的scope
const scopes = ref()
// 已授权的scope
const approvedScopes = ref()
// 提交/拒绝按钮加载状态
const loading = ref(false)

/**
 * 初始化需要授权确认的客户端与scope
 */
getConsentParameters(window.location.search)
  .then((result: any) => {
    if (result.success) {
      consentResult.value = result.data
      scopes.value = [
        ...result.data.previouslyApprovedScopes,
        ...result.data.scopes,
      ]
      approvedScopes.value = result.data.previouslyApprovedScopes.map(
        (e: any) => e.scope,
      )
    }
    else {
      ElMessage({
        message: result.message,
        type: 'warning',
      })
    }
  })
  .catch((e: any) => {
    ElMessage({
      message: `获取客户端与scope信息失败：${e.message || e.statusText}`,
      type: 'warning',
    })
  })

/**
 * 提交授权确认
 *
 * @param cancel true为取消
 */
function submitApprove(cancel: boolean) {
  if (!consentResult.value) {
    ElMessage({
      message: `初始化未完成，无法提交`,
      type: 'warning',
    })
    return
  }
  loading.value = true
  const data = new FormData()
  if (!cancel) {
    // 如果不是取消添加scope
    if (
      approvedScopes.value !== null
      && typeof approvedScopes.value !== 'undefined'
      && approvedScopes.value.length > 0
    ) {
      approvedScopes.value.forEach((e: any) => data.append('scope', e))
    }
  }
  data.append('state', consentResult.value.state)
  data.append('client_id', consentResult.value.clientId)
  data.append('user_code', consentResult.value.userCode)

  submitApproveScope(
    // @ts-expect-error: 忽略类型检查，因为 FormData 转换为 URLSearchParams 时存在类型不匹配的问题
    new URLSearchParams(data),
    consentResult.value.requestURI,
  )
    .then((result: any) => {
      if (result.success) {
        window.location.href = result.data
      }
      else {
        if (result.message && result.message.includes('access_denied')) {
          // 可以跳转至一个单独的页面提醒.
          ElMessage({
            message: '您未选择scope或拒绝了本次授权申请.',
            type: 'warning',
          })
        }
        else {
          ElMessage({
            message: result.message,
            type: 'warning',
          })
        }
      }
    })
    .catch((e: any) => {
      ElMessage({
        message: `提交授权确认失败：${e.message || e.statusText}`,
        type: 'warning',
      })
    })
    .finally(() => (loading.value = false))
}
</script>

<template>
  <main>
    <!-- 验证代码提示 -->
    <el-card v-if="consentResult && consentResult.userCode" class="mb-2">
      <div>
        您已经提供了代码
        <b>{{ consentResult.userCode }}</b>
        ，请验证此代码是否与设备上显示的代码匹配。
      </div>
    </el-card>

    <!-- 客户端信息展示 -->
    <el-card v-if="consentResult" class="mb-2">
      <template #header>
        {{ consentResult.clientName }} 客户端
        <span class="header-extra">账号：<b>{{ consentResult.principalName }}</b></span>
      </template>
      <div>此第三方应用请求获得以下权限：</div>
    </el-card>

    <!-- 权限选择列表 -->
    <el-scrollbar style="max-height: 230px; overflow-y: auto" class="mb-2">
      <el-checkbox-group v-model="approvedScopes">
        <div v-for="scope in scopes" :key="scope.scope" class="permission-item">
          <el-row align="middle">
            <el-col :span="2">
              <el-checkbox :label="scope.scope" />
            </el-col>
            <el-col :span="22">
              <div>
                <b>{{ scope.scope }}</b> - {{ scope.description }}
              </div>
            </el-col>
          </el-row>
        </div>
      </el-checkbox-group>
    </el-scrollbar>

    <!-- 操作按钮 -->
    <el-row>
      <el-col :span="12">
        <el-button
          type="primary"
          :loading="loading"
          style="width: 100%"
          @click="submitApprove(false)"
        >
          确定
        </el-button>
      </el-col>
      <el-col :span="12">
        <el-button
          type="danger"
          :loading="loading"
          style="width: 100%"
          @click="submitApprove(true)"
        >
          拒绝
        </el-button>
      </el-col>
    </el-row>
  </main>
</template>

<style scoped>
header {
  line-height: 1.5;
}

.logo {
  display: block;
  margin: 0 auto 2rem;
}

@media (min-width: 1024px) {
  header {
    display: flex;
    place-items: center;
    padding-right: calc(var(--section-gap) / 2);
  }

  .logo {
    margin: 0 2rem 0 0;
  }

  header .wrapper {
    display: flex;
    place-items: flex-start;
    flex-wrap: wrap;
  }
}

b,
h3,
::v-deep(.n-card-header__main) {
  font-weight: bold !important;
}

.mb-2 {
  margin-bottom: 20px;
}
.header-extra {
  float: right;
  font-size: 14px;
  color: #666;
}
.permission-item {
  margin-bottom: 15px;
}
</style>
